<?php
namespace common\services\SMS;

use Aliyun\Core\Config;
use Aliyun\Core\Profile\DefaultProfile;
use Aliyun\Core\DefaultAcsClient;
use Aliyun\Api\Sms\Request\V20170525\SendSmsRequest;
use common\models\Functions;
use common\models\Status;
use Yii;
use yii\base\Exception;

class SmsAli
{

    private $accessKeyId;                                   //阿里云短信获取的accessKeyId
    private $accessKeySecret;                               //阿里云短信获取的accessKeySecret
    private $signName;                                      //这个是短信签名，要审核通过
    private $templateCode;                                  //短信模板ID，记得要审核通过的
    private $region;                                        //暂时不支持多Region（目前仅支持cn-hangzhou请勿修改）
    private $product = "Dysmsapi";                          //短信API产品名（短信产品名固定，无需修改）
    private $domain = "dysmsapi.aliyuncs.com";              //短信API产品域名（接口地址固定，无需修改）


    public function __construct()
    {
        $this->accessKeyId      = Yii::$app->params['SMS_ALI_ACCESS_KEY_ID'];
        $this->accessKeySecret  = Yii::$app->params['SMS_ALI_ACCESS_KEY_SECRET'];
        $this->signName         = Yii::$app->params['SMS_ALI_SIGN_NAME'];
        $this->templateCode     = Yii::$app->params['SMS_ALI_TEMPLATE_CODE'];
        $this->region           = "cn-hangzhou";
    }

    public function sendCode($phone = '', $type, $time = 5) {
        try {
            $cacheKey = Functions::getVerifyKey($phone,$type);
            //校验时间间隔
//            $cache = Yii::$app->cache;
            $cache = Yii::$app->redis;
            $lastData = json_decode($cache->get($cacheKey), true);
            if (!empty($lastData) && isset($lastData['send_time'])) {
                if ($lastData['send_time'] + 60 > time()) {
                    throw new Exception('时间间隔小于60秒', 2000);
                }

                if ($lastData['send_time'] + $time * 60 > time()) {
                    throw new Exception('验证码'.$time.'分钟内有效，请勿重复发送', 2000);
                }
            }

            $today = date('Ymd');


            $devPhone = Status::TEST_PHONE;

            if (!in_array($phone, $devPhone)) {
                // 限制次数
                $cacheKeyCount = $cacheKey."count".$today;
                if ($cache->exists($cacheKeyCount)) {
                    $cache->incr($cacheKeyCount);
                } else {
                    $cache->set($cacheKeyCount, 1);
                    $cache->expire($cacheKeyCount, strtotime(date("Y-m-d",strtotime("+1 day"))) - time());
                }
                $smsDayCount = (int) $cache->get($cacheKeyCount);
                if ($smsDayCount > 10) {
                    throw new Exception('每天只能发送10条验证码', 2000);
                }

                // 错误次数
                $errCount = $cacheKey."errorCount".$today;
                $errDayCount = (int) $cache->get($errCount);
                if ($errDayCount > 5) {
                    throw new Exception('失败次数过多，请于明天之后尝试', 2000);
                }
            }


            $code = rand(100000, 999999);
            $this->sendMsg($phone, $code);
            $data = [
                'code' => $code,
                'expire_time' => time() + $time * 60,
                'send_time' => time(),
                'to' => $phone
            ];
            $second = $time * 60;
            $cache->set($cacheKey, json_encode($data), 'EX', $second , "NX");
            $cache->expire($cacheKey, $time * 60);

            return Functions::formatJson(1000, '发送成功', $data);
        } catch (Exception $e) {
            return Functions::formatJson(2000, $e->getMessage());
        }
    }

    //阿里短信函数，$mobile为手机号码，$code为自定义随机数
    function sendMsg($mobile,$code){

//        //我这里的路径相对于当前路径的阿里云SDK路径，自己把握
        require_once __DIR__ . '/alisms/vendor/autoload.php';
        Config::load();             //加载区域结点配置

        //这个个是审核过的模板内容中的变量赋值，记住数组中字符串code要和模板内容中的保持一致
        //比如我们模板中的内容为：你的验证码为：${code}，该验证码5分钟内有效，请勿泄漏！
        $templateParam = ["code" => $code];           //模板变量替换


        // 初始化用户Profile实例
        $profile = DefaultProfile::getProfile($this->region,  $this->accessKeyId, $this->accessKeySecret);
        // 增加服务结点
        DefaultProfile::addEndpoint("cn-hangzhou", "cn-hangzhou", $this->product, $this->domain);
        // 初始化AcsClient用于发起请求
        $acsClient= new DefaultAcsClient($profile);

        // 初始化SendSmsRequest实例用于设置发送短信的参数
        $request = new SendSmsRequest();
        // 必填，设置雉短信接收号码
        $request->setPhoneNumbers($mobile);

        // 必填，设置签名名称
        $request->setSignName($this->signName);

        // 必填，设置模板CODE
        $request->setTemplateCode($this->templateCode);

        // 可选，设置模板参数
        if($templateParam) {
            $request->setTemplateParam(json_encode($templateParam));
        }

        //发起访问请求
        $acsResponse = $acsClient->getAcsResponse($request);

        //返回请求结果
        $result = json_decode(json_encode($acsResponse),true);
        return $result;
    }

}
